/*
 * Copyright (c) 2010 CCX(China) Co.,Ltd. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * CCX(China) Co.,Ltd. ("Confidential Information").
 * It may not be copied or reproduced in any manner without the express 
 * written permission of CCX(China) Co.,Ltd.
 *
 * Author: zhnb
 * Date: 2011-4-21 下午02:09:38
 */

package com.ccx.memc;

import java.io.Serializable;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.md5.MD5;

/**
 * 查询执行者类
 * 
 */
public class QueryMemcOperator implements Serializable {

    private static final long serialVersionUID = 1025288123522215184L;
    private static Logger logger = LoggerFactory
            .getLogger(QueryMemcOperator.class);

    // 内存缓存对象
    private MemcachedOpr memc = MemcachedOpr.getInstance();
    // 数据库查询工具类对象
    private QueryUtil qu = new QueryUtil();

    /**
     * 执行入口：业务逻辑(使用默认数据源)
     * 
     * @param sqlStr
     *            sql语句
     * @return
     */
    public String query(String sqlStr) {
        return query(sqlStr, null);
    }

    /**
     * 执行入口：业务逻辑
     * 
     * @param sqlStr
     *            sql语句
     * @param dataSource
     *            数据源名称（null时，取默认ConstUtil.JYDB_ORACLE）
     * @return SQL查询结果
     */
    public String query(String sqlStr, String dataSource) {

        // 待返回的查询结果序列
        String valRet = null;
        // SQL特征码
        String sqlConditCode = null;

        // 1, 判断SQL是否为空
        if (this.isEmpty(sqlStr)) {
            throw new RuntimeException("the sql statement is null");
        }

        // 2, 获取SQL特征码
        sqlConditCode = this.getConditCode(sqlStr);

        // 3, 获取值
        Object obj = this.memc.get(sqlConditCode);
        valRet = (obj == null) ? null : obj.toString();

        // 3-A, 若不存在，则去数据库取值，维护缓存。
        if (valRet == null) {
            // 拿SQL语句去查询数据库
            valRet = this.qu.query(sqlStr, dataSource);
            // 反填缓存
            this.memc.add(sqlConditCode, valRet);

            logger.info("added:(" + sqlConditCode + ", " + valRet + ")");
        }
        // 3-B, 存在，直接返回。

        return valRet;
    }

    /**
     * 查询一个结果集
     * 
     * @param sqlStr
     *            sql语句
     * @param dataSource
     *            数据源名称（null时，取默认ConstUtil.JYDB_ORACLE）
     * @return SQL查询结果集List<Map<> >
     */
    @SuppressWarnings("unchecked")
    public List queryList(String sqlStr, String dataSource) {

        // 待返回的查询结果序列
        List returnList = null;
        // SQL特征码
        String sqlConditCode = null;

        // 1, 判断SQL是否为空
        if (this.isEmpty(sqlStr)) {
            throw new RuntimeException("the sql statement is null");
        }

        // 2, 获取SQL特征码
        sqlConditCode = this.getConditCode(sqlStr);

        // 3, 获取值
        returnList = (List) this.memc.get(sqlConditCode);

        // 3-A, 若不存在，则去数据库取值，维护缓存。
        if (returnList == null) {
            // 拿SQL语句去查询数据库
            returnList = this.qu.queryList(sqlStr, dataSource);
            // 反填缓存
            this.memc.add(sqlConditCode, returnList);

            logger.info("added:(" + sqlConditCode + ", " + returnList + ")");
        }
        // 3-B, 存在，直接返回。

        return returnList;
    }

    /**
     * SQL是否为空
     * 
     * @param sqlStr
     *            sql语句
     * @return 是:true, 否:false
     */
    private boolean isEmpty(String sqlStr) {
        // 为空或空值返回false, 否则true.
        return (sqlStr == null || sqlStr.isEmpty()) ? true : false;
    }

    /**
     * 获取SQL特征码
     * 
     * @param sqlStr
     *            sql语句
     * @return SQL特征码
     */
    private String getConditCode(String sqlStr) {
        // 采用MD5（32b）加密方式
        return MD5.encrypt(sqlStr);
    }

}
